package service

import (
	"encoding/json"
	"fmt"
	"regexp"
	"strings"
	"time"

	"github.com/flipped-aurora/gin-vue-admin/server/global"
	"github.com/flipped-aurora/gin-vue-admin/server/plugin/gva_intelligent_form/model"
	"github.com/flipped-aurora/gin-vue-admin/server/plugin/gva_intelligent_form/model/request"
	"github.com/xuri/excelize/v2"
	"go.uber.org/zap"
	"gorm.io/datatypes"
)

type IntelligentFormSubmissionService struct{}

// SubmitForm 提交表单
func (s *IntelligentFormSubmissionService) SubmitForm(req *request.SubmitFormRequest, userID *uint, ip string) error {
	// 验证表单是否可以提交
	formService := &IntelligentFormService{}
	form, err := formService.GetPublicForm(req.FormID, req.Password)
	if err != nil {
		return err
	}

	// 转换提交数据为JSON
	submitDataBytes, _ := json.Marshal(req.SubmitData)

	// 创建提交记录
	submission := &model.IntelligentFormSubmission{
		FormID:     req.FormID,
		SubmitUser: userID,
		SubmitIP:   ip,
		SubmitData: datatypes.JSON(submitDataBytes),
		SubmitTime: time.Now(),
	}

	// 使用事务确保数据一致性
	tx := global.GVA_DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 创建提交记录
	if err := tx.Create(submission).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 更新表单提交计数
	if err := tx.Model(&model.IntelligentForm{}).Where("id = ?", req.FormID).
		Update("submit_count", form.SubmitCount+1).Error; err != nil {
		tx.Rollback()
		return err
	}

	tx.Commit()
	return nil
}

// GetSubmissionList 获取提交记录列表
func (s *IntelligentFormSubmissionService) GetSubmissionList(info request.IntelligentFormSubmissionSearch) (list []model.IntelligentFormSubmission, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	db := global.GVA_DB.Model(&model.IntelligentFormSubmission{})

	// 添加调试日志
	global.GVA_LOG.Info("GetSubmissionList called",
		zap.Any("FormID", info.FormID),
		zap.Any("Page", info.Page),
		zap.Any("PageSize", info.PageSize),
		zap.Any("SubmitUser", info.SubmitUser),
		zap.Any("StartCreatedAt", info.StartCreatedAt),
		zap.Any("EndCreatedAt", info.EndCreatedAt))

	// 添加搜索条件
	if info.FormID != 0 {
		db = db.Where("form_id = ?", info.FormID)
	}
	if info.SubmitUser != nil {
		db = db.Where("submit_user = ?", *info.SubmitUser)
	}
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}

	err = db.Count(&total).Error
	if err != nil {
		return
	}

	// 添加调试日志
	global.GVA_LOG.Info("Query count result", zap.Int64("total", total))

	err = db.Limit(limit).Offset(offset).Order("created_at DESC").Find(&list).Error

	// 添加调试日志
	global.GVA_LOG.Info("Query list result", zap.Int("count", len(list)), zap.Error(err))

	return list, total, err
}

// GetSubmission 获取提交记录详情
func (s *IntelligentFormSubmissionService) GetSubmission(id uint) (*model.IntelligentFormSubmission, error) {
	var submission model.IntelligentFormSubmission
	err := global.GVA_DB.Where("id = ?", id).First(&submission).Error
	return &submission, err
}

// DeleteSubmission 删除提交记录
func (s *IntelligentFormSubmissionService) DeleteSubmission(id uint) error {
	return global.GVA_DB.Delete(&model.IntelligentFormSubmission{}, id).Error
}

// ExportSubmissions 导出提交数据为Excel
func (s *IntelligentFormSubmissionService) ExportSubmissions(formID *uint, startDate, endDate string) ([]byte, string, error) {
	// 构建查询条件
	db := global.GVA_DB.Model(&model.IntelligentFormSubmission{})
	if formID != nil && *formID != 0 {
		db = db.Where("form_id = ?", *formID)
	}
	if startDate != "" {
		db = db.Where("created_at >= ?", startDate)
	}
	if endDate != "" {
		db = db.Where("created_at <= ?", endDate)
	}

	// 获取提交数据
	var submissions []model.IntelligentFormSubmission
	if err := db.Order("created_at DESC").Find(&submissions).Error; err != nil {
		return nil, "", err
	}

	// 如果有指定表单ID，获取表单信息以获取字段定义
	var form *model.IntelligentForm
	var formFields []map[string]interface{}
	if formID != nil && *formID != 0 {
		formService := &IntelligentFormService{}
		var err error
		form, err = formService.GetIntelligentForm(*formID)
		if err == nil && form.FormConfig != nil {
			// 解析表单配置获取字段信息
			var formConfig map[string]interface{}
			if err := json.Unmarshal(form.FormConfig, &formConfig); err == nil {
				if fields, ok := formConfig["fields"].([]interface{}); ok {
					for _, field := range fields {
						if fieldMap, ok := field.(map[string]interface{}); ok {
							formFields = append(formFields, fieldMap)
						}
					}
				}
			}
		}
	}

	// 创建Excel文件
	f := excelize.NewFile()
	defer func() {
		if err := f.Close(); err != nil {
			global.GVA_LOG.Error("关闭Excel文件失败", zap.Error(err))
		}
	}()

	// 创建新的工作表
	sheetName := "提交数据"
	index, err := f.NewSheet(sheetName)
	if err != nil {
		return nil, "", fmt.Errorf("创建工作表失败: %v", err)
	}

	// 设置表头
	headers := []string{"提交ID", "表单ID", "提交用户", "提交IP", "提交时间"}

	// 如果有字段定义，添加字段列头
	fieldColumns := make(map[string]int)
	if len(formFields) > 0 {
		for _, field := range formFields {
			if label, ok := field["label"].(string); ok {
				headers = append(headers, label)
				fieldColumns[fmt.Sprintf("%v", field["id"])] = len(headers) - 1
			}
		}
	} else {
		// 如果没有字段定义，添加通用的提交数据列
		headers = append(headers, "提交数据")
	}

	// 写入表头
	for i, header := range headers {
		cell, err := excelize.CoordinatesToCellName(i+1, 1)
		if err != nil {
			continue
		}
		f.SetCellValue(sheetName, cell, header)
	}

	// 设置表头样式
	headerStyle, _ := f.NewStyle(&excelize.Style{
		Font: &excelize.Font{Bold: true},
		Fill: excelize.Fill{Type: "pattern", Color: []string{"#E6E6FA"}, Pattern: 1},
	})
	if len(headers) > 0 {
		endCell, err := excelize.CoordinatesToCellName(len(headers), 1)
		if err == nil {
			f.SetCellStyle(sheetName, "A1", endCell, headerStyle)
		}
	}

	// 写入数据
	for rowIndex, submission := range submissions {
		row := rowIndex + 2 // 从第2行开始（第1行是表头）

		// 基本信息
		f.SetCellValue(sheetName, fmt.Sprintf("A%d", row), submission.ID)
		f.SetCellValue(sheetName, fmt.Sprintf("B%d", row), submission.FormID)

		userCell := "匿名用户"
		if submission.SubmitUser != nil {
			userCell = fmt.Sprintf("用户%d", *submission.SubmitUser)
		}
		f.SetCellValue(sheetName, fmt.Sprintf("C%d", row), userCell)
		f.SetCellValue(sheetName, fmt.Sprintf("D%d", row), submission.SubmitIP)
		f.SetCellValue(sheetName, fmt.Sprintf("E%d", row), submission.CreatedAt.Format("2006-01-02 15:04:05"))

		// 解析提交数据
		var submitData map[string]interface{}
		if err := json.Unmarshal(submission.SubmitData, &submitData); err == nil {
			if len(formFields) > 0 {
				// 根据字段定义填充数据
				for fieldID, colIndex := range fieldColumns {
					if value, exists := submitData[fieldID]; exists {
						cell, err := excelize.CoordinatesToCellName(colIndex+1, row)
						if err != nil {
							continue
						}

						// 根据字段类型格式化值
						formattedValue := formatSubmissionValue(value)
						f.SetCellValue(sheetName, cell, formattedValue)
					}
				}
			} else {
				// 如果没有字段定义，将整个数据作为JSON字符串
				dataBytes, _ := json.Marshal(submitData)
				f.SetCellValue(sheetName, fmt.Sprintf("F%d", row), string(dataBytes))
			}
		}
	}

	// 自动调整列宽
	for i := 0; i < len(headers); i++ {
		colName, err := excelize.ColumnNumberToName(i + 1)
		if err != nil {
			continue
		}
		f.SetColWidth(sheetName, colName, colName, 15)
	}

	// 生成文件名
	filename := fmt.Sprintf("submission_data_%s.xlsx", time.Now().Format("20060102_150405"))
	if form != nil {
		safeTitle := sanitizeFilename(form.Title)
		filename = fmt.Sprintf("%s_submission_data_%s.xlsx", safeTitle, time.Now().Format("20060102_150405"))
	} else if formID == nil || *formID == 0 {
		filename = fmt.Sprintf("all_forms_submission_data_%s.xlsx", time.Now().Format("20060102_150405"))
	}

	// 设置活动工作表
	f.SetActiveSheet(index)

	// 保存到缓冲区
	file, err := f.WriteToBuffer()
	if err != nil {
		return nil, "", err
	}

	return file.Bytes(), filename, nil
}

// formatSubmissionValue 格式化提交值
func formatSubmissionValue(value interface{}) string {
	switch v := value.(type) {
	case []interface{}:
		// 多选值，用逗号分隔
		var items []string
		for _, item := range v {
			if item != nil {
				items = append(items, fmt.Sprintf("%v", item))
			}
		}
		return strings.Join(items, ", ")
	case []string:
		// 字符串数组
		return strings.Join(v, ", ")
	case map[string]interface{}:
		// 复杂对象，转为JSON
		bytes, _ := json.Marshal(v)
		return string(bytes)
	case nil:
		return ""
	case string:
		// 字符串值，直接返回
		return v
	default:
		return fmt.Sprintf("%v", v)
	}
}

// sanitizeFilename 清理文件名，移除非法字符
func sanitizeFilename(filename string) string {
	// 移除或替换非法字符
	reg := regexp.MustCompile(`[<>:"/\\|?*]`)
	filename = reg.ReplaceAllString(filename, "_")

	// 移除多余的空格和点
	filename = strings.TrimSpace(filename)
	filename = strings.Trim(filename, ".")

	// 如果文件名为空，使用默认名称
	if filename == "" {
		filename = "表单数据"
	}

	return filename
}

// SubmitGeneratedForm 提交生成的表单（专门用于生成类型的表单，匿名提交）
func (s *IntelligentFormSubmissionService) SubmitGeneratedForm(req *request.SubmitFormRequest, ip string) error {
	// 验证表单是否可以提交（使用生成表单的验证方法）
	formService := &IntelligentFormService{}
	form, err := formService.GetGeneratedForm(req.FormID, req.Password)
	if err != nil {
		return err
	}

	// 转换提交数据为JSON
	submitDataBytes, _ := json.Marshal(req.SubmitData)

	// 创建提交记录（生成表单的提交始终为匿名）
	submission := &model.IntelligentFormSubmission{
		FormID:     req.FormID,
		SubmitUser: nil, // 生成表单始终为匿名提交
		SubmitIP:   ip,
		SubmitData: datatypes.JSON(submitDataBytes),
		SubmitTime: time.Now(),
	}

	// 使用事务确保数据一致性
	tx := global.GVA_DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 创建提交记录
	if err := tx.Create(submission).Error; err != nil {
		tx.Rollback()
		return err
	}

	// 更新表单提交计数
	if err := tx.Model(&model.IntelligentForm{}).Where("id = ?", req.FormID).
		Update("submit_count", form.SubmitCount+1).Error; err != nil {
		tx.Rollback()
		return err
	}

	tx.Commit()
	return nil
}

type IntelligentFormFieldService struct{}
type IntelligentFormTemplateService struct{}
type IntelligentFormAnalyticsService struct{}
